(function($) {
	$.fn.particles = function(opt) {
		opt = (opt == undefined ? {} : ($.isNumeric(opt) ? {
			count : opt
		} : opt));
		// 初始化全局参数
		var height = $(this).height();
		var width = $(this).width();
		var radix = Math.min(height, width);
		var count = (opt.count == undefined ? 20 : opt.count);
		var speed = (opt.speed == undefined ? (radix / 70) : opt.speed);
		var minRradius = (opt.minRradius == undefined ? (radix / 50) : opt.minRradius);
		var maxRradius = (opt.maxRradius == undefined ? (radix / 20) : opt.maxRradius);
		var maxSpeedMul = (opt.maxSpeedMul == undefined ? 2 : opt.maxSpeedMul);
		var millisec = 10;
		if (radix == 0)
			return;
		// 添加画布
		var canvas = $(this).append('<canvas id="particles"></canvas>').children('#particles')[0];
		canvas.height = height;
		canvas.width = width;
		// 绘制对象
		var ctx = canvas.getContext('2d');
		// 添加点
		var ps = [];
		for (i = 0; i < count; i++)
			ps.push(new point());
		// 定时移动
		setInterval(function() {
			clear();
			for (index in ps)
				draw(ps[index].next());
		}, millisec);
		// 添加鼠标定位处理
		var position = getPosition(canvas);
		var mouse = {};
		$(canvas).bind('mousemove', function(event) {
			mouse.x = event.clientX - position.left + $(document).scrollLeft();
			mouse.y = event.clientY - position.top + $(document).scrollTop();
		});
		$(canvas).bind('mouseout', function(event) {
			mouse = {};
		});
		// 点对象
		function point() {
			// 半径
			this.radius = random(minRradius, maxRradius);
			// x坐标
			this.x = random(this.radius, width - this.radius);
			// y坐标
			this.y = random(this.radius, height - this.radius);
			// 颜色
			this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')';
			// 初始横向移动速度
			this.ini_move_x = random(1, speed);
			// 初始纵向移动速度
			this.ini_move_y = random(1, speed);
			// 横向移动
			this.move_x = this.ini_move_x * (random(0, 1) == 0 ? 1 : -1);
			// 纵向移动
			this.move_y = this.ini_move_y * (random(0, 1) == 0 ? 1 : -1);
			// 速度是否改变
			this.su = false;
			// 下一帧
			this.next = function() {
				// 处理鼠标区域
				if (mouse.x != undefined && mouse.y != undefined) {
					// 受力大小
					var tan = (mouse.x - this.x) / (mouse.y - this.y);
					var x_power = Math.sqrt(1 / 10 / (tan * tan + 1));
					var y_power = Math.sqrt(1 / 10 / (1 / tan / tan + 1));
					this.move_x += (mouse.x > this.x ? x_power : -x_power);
					this.move_y += (mouse.y > this.y ? y_power : -y_power);
					// 处理最大速度
					var max_x = Math.max(this.ini_move_x * maxSpeedMul, speed);
					var max_y = Math.max(this.ini_move_y * maxSpeedMul, speed);
					if (Math.abs(this.move_x) > max_x)
						this.move_x = this.move_x > 0 ? max_x : -max_x;
					if (Math.abs(this.move_y) > max_y)
						this.move_y = this.move_y > 0 ? max_y : -max_y;
					this.su = true;
				} else if (this.su) {
					this.move_x = this.move_x > 0 ? this.ini_move_x : -this.ini_move_x;
					this.move_y = this.move_y > 0 ? this.ini_move_y : -this.ini_move_y;
					this.su = false;
				}
				// 校验是否到边界
				if (this.x + this.move_x + this.radius >= width || this.x + this.move_x - this.radius <= 0)
					this.move_x = -this.move_x;
				if (this.y + this.move_y + this.radius >= height || this.y + this.move_y - this.radius <= 0)
					this.move_y = -this.move_y;
				// 调整位置
				this.x = this.x + this.move_x;
				this.y = this.y + this.move_y;
				return this;
			}
		}
		// 绘制图像
		function draw(point) {
			// 开始绘制
			ctx.beginPath();
			// 设置颜色
			ctx.fillStyle = point.color;
			// 画圆
			ctx.arc(point.x, point.y, point.radius, 0, 2 * Math.PI);
			// 关闭路径
			ctx.closePath();
			// 填充
			ctx.fill();
		}
		// 清空绘制
		function clear() {
			ctx.clearRect(0, 0, width, height);
		}
		// 获取随机数
		function random(min, max) {
			return Math.round(Math.random() * (max - min) + min);
		}
		// 获取组件绝对位置
		function getPosition(selector) {
			var p = $(selector).position()
			var top = p.top;
			var left = p.left;
			$.each($(selector).parents(), function(i, v) {
				p = $(v).position();
				top = (p.top > top ? p.top : top);
				left = (p.left > left ? tp.left : left);
			});
			return {
				top : top,
				left : left
			}
		}
	};
})(jQuery);